
#include "../include/hardware_report.h"
u16 syncflag_count = 0;
u64 debug_count = 0;

int synctime_write_file(u16 hcp_mid, u8 *pkt, u16 seq_num)
{
    u16 delay = 0;
    u32 seqid = 0;
    u16 serial_number = 0;
    u16 delay_serial_number = 0;

    u32 gmtime_ns = 0;
    u64 gmtime_s = 0;

    u32 cursyncclk_ns = 0;
    u64 cursyncclk_s = 0;

    u32 clkset_ns = 0;
    u64 clkset_s = 0;

    u16 mac_recvtime_decimal = 0;
    u32 mac_recvtime_integer = 0;

    u16 tsc_recvtime_decimal = 0;
    u32 tsc_recvtime_integer = 0;

    u8 tick_integer = 0;
    u64 tick_decimal = 0;

    u16 corrtime_decimal = 0;
    u64 corrtime_integer = 0;
    opensync_sync_state_pkt *tmp_data = NULL;

    tmp_data = (opensync_sync_state_pkt *)(pkt);

    delay = ntohs(tmp_data->hwdelay);
    seqid = ntohl(tmp_data->ccid);
    serial_number = ntohs(tmp_data->opensync_head.sync_serial_number);
    delay_serial_number = ntohs(tmp_data->opensync_head.delay_serial_number);

    strtime_to_valuetime(tmp_data->gmtime, &gmtime_ns, &gmtime_s);
    strtime_to_valuetime(tmp_data->cursyncclk, &cursyncclk_ns, &cursyncclk_s);
    strtime_to_valuetime(tmp_data->clkset, &clkset_ns, &clkset_s);

    recvtime_to_valuetime(tmp_data->macrecvtime, &mac_recvtime_integer, &mac_recvtime_decimal);
    recvtime_to_valuetime(tmp_data->tscrecvtime, &tsc_recvtime_integer, &tsc_recvtime_decimal);

    corrtime_to_valuetime(tmp_data->corrtime, &corrtime_integer, &corrtime_decimal);
    ticklen_to_valuetime(tmp_data->tick_len, &tick_integer, &tick_decimal);

    SYNC_LOG("sync info: hcp_mid = %hu, sync_serial_number=%u ,delay_serial_number=%u,gmtime = %llu sec %u ns, corrtime = %llu ns %hu 2^(-16)ns,macrecvtime = %u ns %hu 2^(-16)ns,\
tscrecvtime = %u ns %hu 2^(-16)ns,hwdelay = %hu,cursyncclk = %llu sec %u ns,clkset = %llu sec %u ns,cyclestartid = %u,tick_len = %hhu ns %llu 2^(-41)ns\n",
             hcp_mid, serial_number, delay_serial_number, gmtime_s, gmtime_ns, corrtime_integer, corrtime_decimal, mac_recvtime_integer, mac_recvtime_decimal,
             tsc_recvtime_integer, tsc_recvtime_decimal, delay,
             cursyncclk_s, cursyncclk_ns, clkset_s, clkset_ns,
             seqid, tick_integer, tick_decimal);

    return 0;
}

int sync_state_pkt_process(sync_context *sync_para_context, u8 *pkt, sync_state_table *state_table, u8 fre_switch)
{
    u8 local_mac[6] = {0};
    u16 hcp_mid = 0;

    opensync_sync_state_pkt *tmp_data = NULL;
    u8 osm_id = 0;
    u16 serial_number = 0;
    u8 sync_flag = 0;
    u16 count = 0;
    u16 offset = 0;
    int last_hop_cmRate = 0;
    u8 offset_sign = '+';
    u16 offset_sign_tmp = 0;

    node_info *temp_node_info = NULL;
    port_delay_state *temp_delay_state = NULL;
    node_check_info *temp_check_info = NULL;
    u8 tick_interval_flag = 0;
    double neighbor_rate = 0;
    u16 seq_num = 0;
    u16 *max_offset = NULL;
    u16 *min_offset = NULL;

    double rate_ratio = 0;
    int cur_hop_cmRate = 0;
    double corr_fre = 0;
    u64 corr_fre_decimal = 0; // corr_fre的小数部分
    u32 corr_fre_integer = 0; // corr_fre的整数部分
    u32 corr_fre_fcor_h = 0;
    u32 corr_fre_fcor_l = 0;
    u64 corr_fre_reg = 0;
    double tick_interval = 0.0;
    int ret = 0;

    u32 slave_port = 0;
    u32 port_data = 0;

    u8 i = 0;
    u32 bit_value = 0;

    // 从同步状态上报报文中取数据
    tmp_data = (opensync_sync_state_pkt *)(pkt);
    // osm_id = tmp_data->opensync_head.osm_id;
    serial_number = ntohs(tmp_data->opensync_head.sync_serial_number);
    sync_flag = tmp_data->sync_flag;
    count = ntohs(tmp_data->count);
    offset = ntohs(tmp_data->offset) & 0xFFF;                     // 取出bit0~bit11
    offset_sign = (ntohs(tmp_data->offset) & 0x1000) ? '-' : '+'; // 取出bit12，0表示offset为正数，1表示offset为负数
    last_hop_cmRate = ntohl(tmp_data->cumulativeScaledRateOffset);

    offset_sign_tmp = ntohs(tmp_data->offset) & 0x1000;

    // 取出源mac及hcp_mid
    memcpy(local_mac, (u8 *)&tmp_data->tsmp_head.smac, 6);
    hcp_mid = get_mid_from_mac(local_mac);

    synctime_write_file(hcp_mid, pkt, seq_num);

    // 定义指针，便于给sync_para_context赋值
    temp_node_info = sync_para_context->context_info.node_context[hcp_mid];
    slave_port = temp_node_info->cfg_para.slave_port;

    for (i = 0; i < 32; i++)
    {
        bit_value = 0x00000001 << i;
        port_data = ((slave_port & bit_value) != 0) ? 1 : 0;
        if (port_data == 1)
        {
            osm_id = i;
            break;
        }
    }

    temp_delay_state = temp_node_info->delay_state.port_delay_info[osm_id];
    temp_check_info = &temp_node_info->check_info;
    tick_interval_flag = temp_node_info->cfg_para.tick_interval_flag;

    if (tick_interval_flag == 0)
    {
        tick_interval = 8.0;
    }
    else if (tick_interval_flag == 1)
    {
        tick_interval = 6.4;
    }

    // 开辟空间
    if (temp_delay_state == NULL)
    {
        temp_node_info->delay_state.port_delay_info[osm_id] = (port_delay_state *)malloc(sizeof(port_delay_state));
        bzero(temp_node_info->delay_state.port_delay_info[osm_id], sizeof(port_delay_state));

        temp_delay_state = temp_node_info->delay_state.port_delay_info[osm_id];
    }

    neighbor_rate = temp_delay_state->neighbor_rate;
    max_offset = (u16 *)&sync_para_context->sync_state_info.max_offset;
    min_offset = (u16 *)&sync_para_context->sync_state_info.min_offset;
    seq_num = temp_delay_state->seq_num;

    // 将报文中数据放入sync_para_context中
    temp_node_info->sync_state.seq_num = serial_number;
    temp_node_info->sync_state.sync_flag = sync_flag;
    temp_node_info->sync_state.sync_no_ok_count = count;
    temp_node_info->sync_state.offset = offset;
    temp_node_info->sync_state.last_hop_cmRate = last_hop_cmRate;

    // opensync地址空间赋值
    state_table[hcp_mid].node_mid = htonl((u32)hcp_mid);
    state_table[hcp_mid].sync_offset = htonl((u32)offset);

    if (offset_sign_tmp == 0)
    {
        state_table[hcp_mid].offset_sign = 0;
    }
    else
    {
        state_table[hcp_mid].offset_sign = htonl(1);
    }

    printf("sync info: hcp_mid = %hu, offset = %c%u\n", hcp_mid, offset_sign, offset);

    // 同步异常时，记录debug信息
    if (sync_flag == 0 || count != syncflag_count)
    {
        // printf("sync error: hcp_mid = %d, sync_flag = %d, count = %d \n", hcp_mid, sync_flag, count);
        syncflag_count = count;
        write_debug_msg("sync error: hcp_mid = %hu, sync_flag = %u, count = %u \n", hcp_mid, sync_flag, count);
    }

    if (neighbor_rate != 0) // 已有neighbor_rate数据
    {
        // 计算并更新频率校正数据
        rate_ratio = last_hop_cmRate * pow(2, -41) + neighbor_rate;
        temp_node_info->sync_state.RateRatio = rate_ratio;
        cur_hop_cmRate = (rate_ratio - 1.0) * pow(2, 41); // 整形数据，ceil()为向上取整函数
        temp_node_info->sync_state.cur_hop_cmRate = cur_hop_cmRate;

        corr_fre = tick_interval * rate_ratio; // 浮点数
        temp_node_info->sync_state.corr_fre = corr_fre;

        if ((rate_ratio > 1.0009766) || (rate_ratio < 0.9990234))
        {
            write_debug_msg("rate_ratio error: hcp_mid = %hu, rate_ratio = %.10lf \n", hcp_mid, rate_ratio);
        }
        else
        {
            corr_fre_integer = (u32)corr_fre;                              // 整数部分
            corr_fre_decimal = (corr_fre - corr_fre_integer) * pow(2, 41); // 小数部分，单位为2^-41 ns
            corr_fre_fcor_h = ((corr_fre_decimal & 0x000001FF00000000) >> 32) + ((corr_fre_integer & 0x000000FF) << 9);
            corr_fre_fcor_l = corr_fre_decimal & 0x00000000FFFFFFFF;
            corr_fre_reg = (((u64)corr_fre_fcor_h) << 32) + corr_fre_fcor_l;

            if (fre_switch == 1)
            {
                // 配置cur_hop_cmRate值到硬件
                cfg_reg_value_no_check(hcp_mid, pkt, htonl(cur_hop_cmRate), htonl(CUMULATIVE_SCALED_RATE_OFFSET),
                                       CUMULATIVE_SCALED_RATE_REG_OFFSET, CUMULATIVE_SCALED_RATE_REG_BIT, temp_check_info);

                // 配置corr_fre值到硬件
                cfg_corr_fre_value_no_check(hcp_mid, pkt, htonll(corr_fre_reg), htonl(FCOR_H_CFG),
                                            FCOR_H_REG_OFFSET, FCOR_H_REG_BIT, temp_check_info);

                // write_debug_msg("sync_debug: hcp_mid = %d, sync_flag = %d, count = %d \n", hcp_mid, sync_flag, count);
                // write_debug_msg("sync_debug: last_hop_cmRate = %d \n", last_hop_cmRate);
                // write_debug_msg("sync_debug: neighbor_rate = %.10lf, rate_ratio = %.10lf, cur_hop_cmRate = %d \n", neighbor_rate, rate_ratio, cur_hop_cmRate);
                // write_debug_msg("sync_debug: corr_fre = %lf, corr_fre_integer = %u, corr_fre_decimal = %llX \n", corr_fre, corr_fre_integer, corr_fre_decimal);
                // write_debug_msg("sync_debug: corr_fre_reg = %llX \n", corr_fre_reg);
            }
        }
    }

    if (debug_count > 200)
    {
        // 更新最大offset值
        if (offset > *max_offset)
        {
            *max_offset = offset;
        }

        // 更新最小offset值
        if (offset < *min_offset)
        {
            *min_offset = offset;
        }

        OFFSET_LOG("sync info: hcp_mid = %hu, offset = %c%hu, max_offset = %d\n", hcp_mid, offset_sign, offset, *max_offset);
    }
    else
    {
        OFFSET_LOG("sync info: hcp_mid = %hu, offset = %c%hu\n", hcp_mid, offset_sign, offset);
    }

    SYNC_LOG("offset = %c%hu,sync_flag = %hhu,count = %u,last_hop_cmRate=%d,cur_hop_cmRate=%d,rate_ratio= %.10lf,corr_fre=%.10lf,osm_id=%d \n",
             offset_sign, offset, sync_flag, count, last_hop_cmRate, cur_hop_cmRate, rate_ratio, corr_fre, osm_id);

    debug_count++;
    return 0;
}

int delay_state_pkt_process(sync_context *sync_para_context, u8 *pkt, u8 fre_switch)
{
    u8 local_mac[6] = {0};
    u16 hcp_mid = 0;

    opensync_delay_state_pkt *tmp_data = NULL;
    u32 ptp_enable_info = 0;
    u8 osm_id = 0;
    u16 serial_number = 0;
    u16 sync_serial_number = 0;
    port_delay_state *temp_delay_state = NULL;
    u32 sub_t1_t4 = 0;
    u32 sub_t2_t3 = 0;
    u16 delay = 0;
    u32 bit_value = 1;
    u16 seq_num = 0;
    double neighbor_rate = 0;
    u16 *max_delay = NULL;
    u16 *min_delay = NULL;
    int i = 0;
    int ret = 0;
    u32 *read_data = NULL; // 读回来的数据
    u8 ptr = 0;
    u64 sub_value1 = 0;
    u64 sub_value2 = 0;

    u64 last_t3_s = 0;
    u32 last_t3_ns = 0;

    u64 last_t4_s = 0;
    u32 last_t4_ns = 0;
    u8 tmp_time[10] = {0};
    u8 tmp_time_null[10] = {0};

    memset(tmp_time, 0xFF, 10);
    printf("tmp_time = %s", tmp_time);

    // 从链路测量状态上报报文中取数据
    tmp_data = (opensync_delay_state_pkt *)(pkt);
    ptp_enable_info = ntohl(tmp_data->port_ptp_enabled);
    osm_id = tmp_data->opensync_head.osm_id;
    serial_number = ntohs(tmp_data->opensync_head.delay_serial_number);
    sync_serial_number = ntohs(tmp_data->opensync_head.sync_serial_number);
    // 取出源mac及hcp_mid
    memcpy(local_mac, (u8 *)&tmp_data->tsmp_head.smac, 6);
    hcp_mid = get_mid_from_mac(local_mac);

    // 定义指针，给sync_para_context赋值
    max_delay = (u16 *)&sync_para_context->delay_state_info.max_delay;
    min_delay = (u16 *)&sync_para_context->delay_state_info.min_delay;

    DELAY_LOG("delay info: hcp_mid = %hu, delay_serial_number = %u,sync_serial_number = %u\n", hcp_mid, serial_number, sync_serial_number);

    for (i = 0; i < MAX_PORT_NUM; i++)
    {
        if (ptp_enable_info & bit_value) // 当前端口ptp使能
        {
            temp_delay_state = sync_para_context->context_info.node_context[hcp_mid]->delay_state.port_delay_info[i];

            // 开辟空间
            if (temp_delay_state == NULL)
            {
                sync_para_context->context_info.node_context[hcp_mid]->delay_state.port_delay_info[i] = (port_delay_state *)malloc(sizeof(port_delay_state));
                bzero(sync_para_context->context_info.node_context[hcp_mid]->delay_state.port_delay_info[i], sizeof(port_delay_state));

                temp_delay_state = sync_para_context->context_info.node_context[hcp_mid]->delay_state.port_delay_info[i];
            }

            seq_num = temp_delay_state->seq_num;

            // 更新序列号
            temp_delay_state->seq_num = serial_number;

            t1_t2_t3_t4_write_file(i, tmp_data->link_state_info[ptr].t1, tmp_data->link_state_info[ptr].t2, tmp_data->link_state_info[ptr].t3, tmp_data->link_state_info[ptr].t4);

            // 如果该端口t1、t2、t3、t4值，有一个时间为全F，说明该端口测量值本次无效
            if ((0 == memcmp(tmp_data->link_state_info[ptr].t1, tmp_time, 10)) || (0 == memcmp(tmp_data->link_state_info[ptr].t2, tmp_time, 10)) ||
                (0 == memcmp(tmp_data->link_state_info[ptr].t3, tmp_time, 10)) || (0 == memcmp(tmp_data->link_state_info[ptr].t4, tmp_time, 10)))
            {
                write_debug_msg("delay error! hcp_mid=%hu,port_id=%u,serial_number = %u,t1 or t2 or t3 0r t4 0xff \n", hcp_mid, i, serial_number);
                ptr++;
                bit_value = bit_value << 1;
                continue;
            }

            // 计算t4-t1值
            sub_t1_t4 = sub_time_compute((u8 *)&tmp_data->link_state_info[ptr].t4, (u8 *)&tmp_data->link_state_info[ptr].t1);
            if (sub_t1_t4 == 0)
            {
                write_debug_msg("delay error! hcp_mid=%hu,port_id=%u,serial_number = %u,t1 || t4 = 0. or t4 < = t1 \n", hcp_mid, i, serial_number);
                ptr++;
                bit_value = bit_value << 1;
                continue;
            }

            // 计算t3-t2值
            sub_t2_t3 = sub_time_compute((u8 *)&tmp_data->link_state_info[ptr].t3, (u8 *)&tmp_data->link_state_info[ptr].t2);
            if (sub_t2_t3 == 0)
            {
                write_debug_msg("delay error!hcp_mid=%hu,port_id=%u,serial_number = %u, t2 || t3 = 0. or t3 < = t2 \n", hcp_mid, i, serial_number);
                ptr++;
                bit_value = bit_value << 1;
                continue;
            }

            if ((seq_num != 0) && (0 != memcmp(temp_delay_state->t3, tmp_time_null, 10)) && (0 != memcmp(temp_delay_state->t4, tmp_time_null, 10)))
            {
                // 计算t3 -last_t3值
                sub_value1 = sub_time_compute((u8 *)&tmp_data->link_state_info[ptr].t3, (u8 *)&temp_delay_state->t3);
                if (sub_value1 == 0)
                {
                    write_debug_msg("delay error! hcp_mid=%hu,port_id=%u,serial_number = %u,t3 || last_t3 = 0. or t3 < = last_t3 \n", hcp_mid, i, serial_number);
                    ptr++;
                    bit_value = bit_value << 1;
                    continue;
                }

                // 计算t4 -last_t4值
                sub_value2 = sub_time_compute((u8 *)&tmp_data->link_state_info[ptr].t4, (u8 *)&temp_delay_state->t4);
                if (sub_value2 == 0)
                {
                    write_debug_msg("delay error! hcp_mid=%hu,port_id=%u,serial_number = %u,t4 || last_t4 = 0. or t4 < = last_t4 \n", hcp_mid, i, serial_number);
                    ptr++;
                    bit_value = bit_value << 1;
                    continue;
                }
            }

            // 更新neighbor_rate

            if ((seq_num != 0) && (0 != memcmp(temp_delay_state->t3, tmp_time_null, 10)) && (0 != memcmp(temp_delay_state->t4, tmp_time_null, 10))) // 代表已经第二次收到链路延时报文了
            {
                neighbor_rate = (double)sub_value1 / (double)sub_value2;
                if ((neighbor_rate > 1.0019531) || (neighbor_rate < 0.9980469))
                {
                    write_debug_msg("delay error!hcp_mid=%hu,port_id=%u,serial_number = %u, neighbor_rate=%.10lf\n", hcp_mid, i, serial_number, neighbor_rate);
                    ptr++;
                    bit_value = bit_value << 1;
                    continue;
                }
                else
                {
                    temp_delay_state->neighbor_rate = neighbor_rate;
                }
            }

            // 更新last_t3和last_t4
            memcpy((u8 *)&temp_delay_state->last_t3, (u8 *)&temp_delay_state->t3, 10);
            strtime_to_valuetime(temp_delay_state->t3, &last_t3_ns, &last_t3_s);

            memcpy((u8 *)&temp_delay_state->last_t4, (u8 *)&temp_delay_state->t4, 10);
            strtime_to_valuetime(temp_delay_state->t4, &last_t4_ns, &last_t4_s);

            // 更新本次测量时的t1、t2、t3和t4
            memcpy((u8 *)&temp_delay_state->t1, (u8 *)&tmp_data->link_state_info[ptr].t1, 10);
            memcpy((u8 *)&temp_delay_state->t2, (u8 *)&tmp_data->link_state_info[ptr].t2, 10);
            memcpy((u8 *)&temp_delay_state->t3, (u8 *)&tmp_data->link_state_info[ptr].t3, 10);
            memcpy((u8 *)&temp_delay_state->t4, (u8 *)&tmp_data->link_state_info[ptr].t4, 10);

            // 更新sub_t1_t4和sub_t2_t3
            temp_delay_state->sub_t1_t4 = sub_t1_t4;
            temp_delay_state->sub_t2_t3 = sub_t2_t3;

            // 更新delay
            delay = (sub_t1_t4 - sub_t2_t3) / 2;
            temp_delay_state->delay = delay;

            printf("delay info: hcp_mid = %hu, port = %u, delay = %u \n", hcp_mid, i, delay);

            // 异常处理
            if ((delay > 2000) || ((seq_num + 1) != serial_number))
            {
                // printf("delay error: seq_num+1 = %d, serial_number = %d \n", seq_num + 1, serial_number);
                write_debug_msg("delay error: seq_num+1 = %u, serial_number = %u \n", seq_num + 1, serial_number);

                // printf("delay error: hcp_mid = %d, port = %d, delay = %d \n", hcp_mid, i, delay);
                write_debug_msg("delay error: hcp_mid = %hu, port = %u, delay = %u \n", hcp_mid, i, delay);

                // 异常时去读MEASURE_REQ_COUNT、MEASURE_REQ_ERR_COUNT、MEASURE_RESP_COUNT、MEASURE_RESP_ERR_COUNT
                // read_reg_value(local_mac, 2, htonl(MEASURE_REQ_COUNT_BASE_REG + 2 * i), pkt);
            }

            // 更新最大delay值
            if (delay > *max_delay)
            {
                *max_delay = delay;
            }

            // 更新最小delay值
            if (delay < *max_delay)
            {
                *min_delay = delay;
            }

            // 更新max_neighbor_rate
            if (neighbor_rate > temp_delay_state->max_neighbor_rate)
            {
                temp_delay_state->max_neighbor_rate = neighbor_rate;
            }

            ptr++;

            // write_debug_msg("delay info: hcp_mid = %d, seq_num = %d, neighbor_rate = %.10lf \n", hcp_mid, seq_num, neighbor_rate);
            if (fre_switch == 1)
                printf("delay info: hcp_mid = %hu, seq_num = %u, neighbor_rate = %.10lf \n", hcp_mid, seq_num, neighbor_rate);

            DELAY_LOG("last_t3 = %llu sec %u ns,last_t4 = %llu sec %u ns, delay = %d ns,sub_t1_t4=%u ns,sub_t2_t3=%u ns,neighbor_rate=%.10lf,max_neighbor_rate=%.10lf \n",
                      last_t3_s, last_t3_ns, last_t4_s, last_t4_ns, delay, sub_t1_t4, sub_t2_t3, neighbor_rate, temp_delay_state->max_neighbor_rate);
        }

        bit_value = bit_value << 1;
    }

    return ret;
}
